/**
 * Nakov Chat Server - (c) Svetlin Nakov, 2002
 *
 * Sends messages to the client. Messages are stored in a message queue. When
 * the queue is empty, ClientSender falls in sleep until a new message is
 * arrived in the queue. When the queue is not empty, ClientSender sends the
 * messages from the queue to the client socket.
 */


import java.io.*;
import java.net.*;
import java.util.*;

public class ClientSender extends Thread
{
    private Vector mMessageQueue = new Vector();
    private ServerDispatcher mServerDispatcher;
    private ClientInfo mClientInfo;
    private PrintWriter mOut;

    private int majorVersion = 1;
    private int minorVersion = 0;
    public String version =  majorVersion + "." + minorVersion;
    public String welcome = "Welcome";
    public String serverWelcomeMessage = "CHAT" + "/" + version + "/" + welcome;

    public ClientSender(ClientInfo aClientInfo, ServerDispatcher aServerDispatcher)
    throws IOException
    {
        mClientInfo = aClientInfo;
        mServerDispatcher = aServerDispatcher;
        Socket socket = aClientInfo.mSocket;
        mOut = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
    }

    /**
     * Adds given message to the message queue and notifies this thread
     * (actually getNextMessageFromQueue method) that a message is arrived.
     * sendMessage is called by other threads (ServeDispatcher).
     */
    public synchronized void sendMessage(String aMessage)
    {
        mMessageQueue.add(aMessage);
        notify();
    }

    /**
     * @return and deletes the next message from the message queue. If the queue
     * is empty, falls in sleep until notified for message arrival by sendMessage
     * method.
     */
    private synchronized String getNextMessageFromQueue() throws InterruptedException
    {
        while (mMessageQueue.isEmpty())
           wait();
        String message = (String) mMessageQueue.get(0);
        mMessageQueue.removeElementAt(0);
        return message;
    }
	
    /**
     * Sends given message to the client's socket.
     */	 
    private void sendMessageToClient(String aMessage)
    {
        mOut.print(aMessage+"\r\n");
        mOut.flush();
    }

    /**
     * Until interrupted, reads messages from the message queue
     * and sends them to the client's socket.
     */
    public void run()
    {
        String msg = "";
        try {
            sendMessageToClient(serverWelcomeMessage);
            while (true)
            {
                msg = (String)getNextMessageFromQueue();				
                if(msg.matches("CHAT"))
                {
                    sendMessageToClient("+OK");
                    break;
                }
                else{
                    sendMessageToClient("-Something went wrong");
                }
            }
            while (true)
            {
                msg = (String)getNextMessageFromQueue();
                if (msg.matches("USER"))
                {
                    sendMessageToClient("+USER OK");
                    break;
                }
                else if(msg.matches("INUSE")){
                    sendMessageToClient("-Username in use");
                }
                else{
                    sendMessageToClient("-Invalid user name only use"
                            + "[a-zA-Z_0-9] with a maximum of 20 characters");
                }
            }
            sendMessageToClient("You are now connected to the chat\n"
                    + "Welcome\n\r");
        while (!isInterrupted()) {
           msg = getNextMessageFromQueue();
           sendMessageToClient(msg);
           }
        } catch (Exception e) {
           // Communication problem
        }
        // Communication is broken. Interrupt both listener and sender threads
        mClientInfo.mClientListener.interrupt();
    }

 

}